<template>
	<view class="sel-seat">
		<!-- top -->
		<view class="seat-head">
			<text class="sh-title">{{ title }}</text>
			<text class="sh-info">{{ info }}</text>
		</view>
		<!-- main -->
		<view class="seat-main">
			<movable-area :style="'height:'+(seatRow*40+350)+'rpx;'" class="vm-area">
				<movable-view :style="'width: 750rpx;height:'+(seatRow*40+350)+'rpx;'" :inertia="true" :scale="true"
					:scale-min="0.95" :scale-max="2" direction="all" @change="onMove" @scale="onScale">
					<view class="sm-title">
						<text class="text">影院银幕</text>
					</view>
					<view class="sm-screen">
						<text class="text">{{roomName}}</text>
					</view>
					<view class="sm-line-center"></view>
					<!-- seat content -->
					<view v-for="(item,index) in seatArray" :key="index" class="sm-cell"
						:style="'width:'+boxWidth+'px;height:'+seatSize+'px'">
						<view v-for="(seat,col) in item" :key="col" class="dp-ib"
							:style="'width:'+seatSize+'px;height:'+seatSize+'px'" @click="handleChooseSeat(index,col,seat.IsLove)">
							<image v-if="seat.type===0 && seat.IsLove ===0" class="sm-icon" src="/static/unselected.png" mode="aspectFit">
							</image>
							<image v-else-if="seat.type===1" class="sm-icon" src="/static/selected.png"
								mode="aspectFit"></image>
							<image v-else-if="seat.type===2" class="sm-icon" src="/static/bought.png" mode="aspectFit">
							</image>
							<image v-else-if="seat.type===0 && seat.IsLove !=0" class="sm-icon" src="/static/ql.png" mode="aspectFit">
							</image>
						</view>
					</view>
					<view class="sm-line-index" :style="'left: '+(10-moveX/scale)+'px;'">
						<text class="text" :style="'height:'+seatSize+'px;'" v-for="(m,mindex) in mArr"
							:key="mindex">{{m}}</text>
					</view>
				</movable-view>
			</movable-area>
			<view class="fix-tips" v-if="showTis">
				<view class="v-tips">
					<image :style="'width:'+seatSize+'px;height:'+seatSize+'px'" src="/static/unselected.png"
						mode="aspectFit"></image>
					<text class="text">可选</text>
				</view>
				<view class="v-tips">
					<image :style="'width:'+seatSize+'px;height:'+seatSize+'px'" src="/static/bought.png"
						mode="aspectFit"></image>
					<text class="text">不可选</text>
				</view>
				<view class="v-tips">
					<image :style="'width:'+seatSize+'px;height:'+seatSize+'px'" src="/static/selected.png"
						mode="aspectFit"></image>
					<text class="text">选中</text>
				</view>
				<view class="v-tips">
					<image :style="'width:'+seatSize+'px;height:'+seatSize+'px'" src="/static/ql.png"
						mode="aspectFit"></image>
					<text class="text">情侣座</text>
				</view>
			</view>
		</view>
		<!-- foot -->
		<view class="seat-foot">
			<view class="sf-recommend" v-if="SelectNum === 0">
				<text class="text">推荐选座</text>
				<view class="sfr-tag" v-for="num in Math.min(max, 6)" :key="num" @click="smartChoose(num+1)">
					<text class="text">{{ num+1 }}人</text>
				</view>
			</view>
			<view class="sf-arselect" v-else>
				<text class="text">已选</text>
				<scroll-view scroll-x="true">
					<view class="scr-wrap">
						<view class="sfr-selt" v-for="(optItem,optindex) in optArr" :key="optItem.SeatCode"
							@click="handleChooseSeat(optItem.rowIndex, optItem.colIndex,optItem.IsLove)">
							<!-- <image src="/static/close.png" class="sfr-close"></image> -->
							<text class="text">{{optItem.RowNum+'排'+optItem.ColumnNum+'座'}}</text>
							<text class="price">￥{{ optItem.Price || '' }}</text>
							<view class="sfr-close">X</view>
						</view>
					</view>
				</scroll-view>
			</view>
			<view class="f-btn" :class="{disabled: SelectNum === 0 }" @click="buySeat">
				<text class="text">{{SelectNum === 0 ? '请选座位' : `￥ ${aPrice} 确认座位`}}</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		name: "anil-seat",
		props: {
			seatData: {
				type: Array
			},
			max: {
				type: Number,
				default: 4
			},
			title: {
				type: String,
				default: ''
			},
			info: {
				type: String,
				default: ''
			},
			roomName: {
				type: String,
				default: ''
			}
		},
		data() {
			return {
				scaleMin: 1, //h5端为解决1无法缩小问题，设为0.95
				boxWidth: 400, //屏幕宽度px
				space: ' ', //空格
				seatArray: [], //影院座位的二维数组,-1为非座位，0为未购座位，1为已选座位(绿色),2为已购座位(红色),一维行，二维列
				seatRow: 0, //影院座位行数
				seatCol: 0, //影院座位列数
				seatSize: 0, //座位尺寸
				SelectNum: 0, //选择座位数
				moveX: 0, //水平移动偏移量
				scale: 1, //放大倍数
				minRow: 0, //从第几行开始排座位
				minCol: 0, //从第几列开始排座位
				showTis: true, //显示选座提示
				seatList: [], //接口获取的原始位置
				mArr: [], //排数提示
				optArr: [], //选中的座位数组。
				isWXAPP: false,
			};
		},
		computed: {
			aPrice() {
				let totalAmount =0
				if (this.optArr && this.optArr.length) {
					console.log(this.optArr.length)
					for (var i = 0; i < this.optArr.length; i++) {
						console.log(totalAmount)
						totalAmount=(parseFloat(totalAmount) + parseFloat(this.optArr[i].Price)).toFixed(2)
					}
					//totalAmount = this.optArr.map(item => Number(item.Price)).reduce((prev, curr) => prev + curr)
				}
				return totalAmount
			},
			rpxNum() {
				return this.boxWidth / 750
			},
			pxNum() {
				return 750 / this.boxWidth
			},
		},
		created() {
			//获取宽度
			uni.getSystemInfo({
				success: (e) => {
					this.boxWidth = e.screenWidth
					//#ifdef H5
					this.scaleMin = 0.95
					//#endif
				}
			})
			this.initData()
		},
		methods: {
			initData: function() {
				let arr = this.seatData

				//假数据说明：SeatCode座位编号，RowNum-行号，ColumnNum-纵号，YCoord-Y坐标，XCoord-X坐标，Status-状态
				let row = 0
				let col = 0
				let minCol = parseInt(arr[0].XCoord)
				let minRow = parseInt(arr[0].YCoord)
				for (let i of arr) {

					minRow = parseInt(i.YCoord) < minRow ? parseInt(i.YCoord) : minRow
					minCol = parseInt(i.XCoord) < minCol ? parseInt(i.XCoord) : minCol
					row = parseInt(i.YCoord) > row ? parseInt(i.YCoord) : row
					col = parseInt(i.XCoord) > col ? parseInt(i.XCoord) : col

				}

				this.seatList = arr
				this.seatRow = row - minRow + 1
				this.seatCol = col - minCol + 3
				this.minRow = minRow
				this.minCol = minCol - 1
				////console.log(this.seatRow,this.seatCol,this.minRow,this.minCol)
				this.initSeatArray()
			},
			//初始座位数组
			initSeatArray: function() {
				let seatArray = Array(this.seatRow).fill(0).map(() => Array(this.seatCol).fill({
					type: -1,
					SeatCode: '',
					RowNum: '',
					ColumnNum: ''
				}));
				this.seatArray = seatArray
				this.seatSize = this.boxWidth > 0 ?
					parseInt(parseInt(this.boxWidth, 10) / (this.seatCol + 1), 10) :
					parseInt(parseInt(414, 10) / (this.seatCol + 1), 10)
				this.initNonSeatPlace();
			},
			//初始化是座位的地方
			initNonSeatPlace: function() {
				let seat = this.seatList.slice()
				let arr = this.seatArray.slice()
				for (let num in seat) {
					let status = 2 //-1为非座位，0为未购座位，1为已选座位(绿色),2为已购座位(红色)
					if (seat[num].Status === 0) {
						status = 0
					} else if (seat[num].Status === -1) {
						status = -1
					}
					arr[parseInt(seat[num].YCoord) - this.minRow][parseInt(seat[num].XCoord) - this.minCol] = {
						type: status,
						SeatCode: seat[num].SeatCode,
						RowNum: seat[num].RowNum,
						ColumnNum: seat[num].ColumnNum,
						Price: seat[num].Price,
						SeatIndex: seat[num].SeatIndex,
						IsLove :seat[num].IsLove
					}
				}
				this.seatArray = arr.slice()
				let mArr = []
				for (let i in arr) {
					let m = ''
					for (let n of arr[i]) {
						if (n.SeatCode) {
							m = n.RowNum
						}
					}
					if (m) {
						mArr.push(m)
					} else {
						mArr.push('')
					}
				}
				this.mArr = mArr
			},
			//放大缩小事件
			onScale: function(e) {
				this.showTis = false
				// this.moveX=-e.detail.x
				let w = this.boxWidth * 0.5
				let s = 1 - e.detail.scale
				this.moveX = w * s
				this.scale = e.detail.scale
				if (s > 0 || s === 0) {
					this.showTis = true
				}
			},
			//移动事件
			onMove: function(e) {
				this.showTis = false
				this.moveX = e.detail.x
			},
			//重置座位
			resetSeat: function() {
				this.SelectNum = 0
				this.optArr = []
				//将所有已选座位的值变为0
				let oldArray = this.seatArray.slice();
				for (let i = 0; i < this.seatRow; i++) {
					for (let j = 0; j < this.seatCol; j++) {
						if (oldArray[i][j].type === 1) {
							oldArray[i][j].type = 0
						}
					}
				}
				this.seatArray = oldArray;
			},
			//选定且购买座位
			buySeat: function() {
				let that = this;
				if (this.SelectNum === 0) return;
				let mincol = -1
				let maxcol = -1
				let rowlist = []
				that.optArr[0]['isok'] = true
				let row = 0
				let col = 0
				for (var i = 0; i < that.optArr.length; i++) {
					if(row != 0 && row!= that.optArr[i].rowIndex){
						that.optArr[i]['isok'] = false
						break
					}
					
					row = that.optArr[i].rowIndex
					col = that.optArr[i].colIndex
					mincol = -1
					maxcol = -1
					for (var j = 0; j < that.seatArray[row].length; j++) {

						if (that.seatArray[row][j].type != -1 && mincol == -1) {

							mincol = j
						}
						if (that.seatArray[row][j].type != -1) {

							maxcol = j
						}
					}
					if(col == mincol || col == maxcol){
						that.optArr[i]['isok'] = true
					}else if((col-1 == mincol && that.seatArray[row][mincol].type== 0 && that.seatArray[row][col+1].type== 0)|| (col+1 == maxcol&& that.seatArray[row][maxcol].type== 0 && that.seatArray[row][col-1].type== 0)){
						that.optArr[i]['isok'] = false
					}else if(col - 2 >= mincol && that.seatArray[row][col+1].type== 0 && that.seatArray[row][col-1].type== 0 && that.seatArray[row][col-2].type != 0){
						that.optArr[i]['isok'] = false
					}else if(col + 2 <= maxcol && that.seatArray[row][col-1].type== 0 && that.seatArray[row][col+1].type== 0 && that.seatArray[row][col+2].type != 0
					){
						
						that.optArr[i]['isok'] = false
					}else{
						that.optArr[i]['isok'] = true
					}
					
					
				}

				this.$emit('confirm', that.optArr)
			},
			//处理座位选择逻辑
			handleChooseSeat: function(row, col,love) {
				
				let seatValue = this.seatArray[row][col].type;
				let newArray = this.seatArray;
				//如果是已购座位，直接返回
				//console.log(row, col,love,this.seatArray[row])
				if (seatValue === 2 || seatValue === -1) return
				//如果是已选座位点击后变未选
				if (seatValue === 1) {
					newArray[row][col].type = 0
					this.SelectNum--
					this.getOptArr(newArray[row][col], 0)
					if(love >0){
						if ((love&1) === 0) {
							newArray[row][col-1].type = 0
							this.SelectNum--
							this.getOptArr(newArray[row][col-1], 0)
						} else {
						 	// 奇数  
							newArray[row][col+1].type = 0
							this.SelectNum--
							this.getOptArr(newArray[row][col+1], 0)
						}

					}
					
				} else if (seatValue === 0) {
					if (this.SelectNum >= this.max) {
						return uni.showToast({
							title: '一次最多选择' + this.max + '张',
							icon: 'none'
						})
					}
					newArray[row][col].rowIndex = row
					newArray[row][col].colIndex = col
					newArray[row][col].type = 1
					this.SelectNum++
					this.getOptArr(newArray[row][col], 1)
					if(love >0){
						if ((love&1) === 0) {
							console.log('a')
							newArray[row][col-1].rowIndex = row
							newArray[row][col-1].colIndex = col-1
							newArray[row][col-1].type = 1
							this.SelectNum++
							this.getOptArr(newArray[row][col-1], 1)
						} else {
						 	// 奇数  
							newArray[row][col+1].rowIndex = row
							newArray[row][col+1].colIndex = col+1
							newArray[row][col+1].type = 1
							this.SelectNum++
							this.getOptArr(newArray[row][col+1], 1)
						}
					
					}
				}
				//必须整体更新二维数组，Vue无法检测到数组某一项更新,必须slice复制一个数组才行
				this.seatArray = newArray.slice();

			},
			//处理已选座位数组
			getOptArr: function(item, type) {
				let optArr = this.optArr
				if (type === 1) {
					optArr.push(item)
				} else if (type === 0) {
					let arr = []
					optArr.forEach(v => {
						if (v.SeatCode !== item.SeatCode) {
							arr.push(v)
						}
					})
					optArr = arr
				}
				this.optArr = optArr.slice()
			},
			//推荐选座,参数是推荐座位数目，
			smartChoose: function(num) {
				// //console.log('num===', num)
				// 先重置
				this.resetSeat()
				//找到影院座位水平垂直中间位置的后一排
				let rowStart = parseInt((this.seatRow - 1) / 2, 10) + 1;
				//先从中间排往后排搜索
				let backResult = this.searchSeatByDirection(rowStart, this.seatRow - 1, num);
				if (backResult.length > 0) {
					this.chooseSeat(backResult);
					this.SelectNum += num
					return
				}
				//再从中间排往前排搜索
				let forwardResult = this.searchSeatByDirection(rowStart - 1, 0, num);
				if (forwardResult.length > 0) {
					this.chooseSeat(forwardResult);
					this.SelectNum += num
					return
				}
				//提示用户无合法位置可选
				// #ifdef H5
				alert('无合法位置可选!')
				// #endif
			},

			//搜索函数,参数:fromRow起始行，toRow终止行,num推荐座位数
			searchSeatByDirection: function(fromRow, toRow, num) {
				/*
				 * 推荐座位规则
				 * (1)初始状态从座位行数的一半处的后一排的中间开始向左右分别搜索，取离中间最近的，如果满足条件，
				 *    记录下该结果离座位中轴线的距离，后排搜索完成后取距离最小的那个结果座位最终结果，优先向后排进行搜索，
				 *    后排都没有才往前排搜，前排逻辑同上
				 *
				 * (2)只考虑并排且连续的座位，不能不在一排或者一排中间有分隔
				 *
				 * */

				/*
				 * 保存当前方向搜索结果的数组,元素是对象,result是结果数组，offset代表与中轴线的偏移距离
				 * {
				 *   result:Array([x,y])
				 *   offset:Number
				 * }
				 *
				 */
				let currentDirectionSearchResult = [];

				let largeRow = fromRow > toRow ? fromRow : toRow,
					smallRow = fromRow > toRow ? toRow : fromRow;

				for (let i = smallRow; i <= largeRow; i++) {
					//每一排的搜索,找出该排里中轴线最近的一组座位
					let tempRowResult = [],
						minDistanceToMidLine = Infinity;
					for (let j = 0; j <= this.seatCol - num; j++) {
						//如果有合法位置
						if (this.checkRowSeatContinusAndEmpty(i, j, j + num - 1)) {
							//计算该组位置距离中轴线的距离:该组位置的中间位置到中轴线的距离
							let resultMidPos = parseInt((j + num / 2), 10);
							let distance = Math.abs(parseInt(this.seatCol / 2) - resultMidPos);
							//如果距离较短则更新
							if (distance < minDistanceToMidLine) {
								minDistanceToMidLine = distance;
								//该行的最终结果
								tempRowResult = this.generateRowResult(i, j, j + num - 1)
							}
						}
					}
					//保存该行的最终结果
					currentDirectionSearchResult.push({
						result: tempRowResult,
						offset: minDistanceToMidLine
					})
				}

				//处理后排的搜索结果:找到距离中轴线最短的一个
				//注意这里的逻辑需要区分前后排，对于后排是从前往后，前排则是从后往前找
				let isBackDir = fromRow < toRow;
				let finalReuslt = [],
					minDistanceToMid = Infinity;
				if (isBackDir) {
					//后排情况,从前往后
					currentDirectionSearchResult.forEach((item) => {
						if (item.offset < minDistanceToMid) {
							finalReuslt = item.result;
							minDistanceToMid = item.offset;
						}
					});
				} else {
					//前排情况，从后往前找
					currentDirectionSearchResult.reverse().forEach((item) => {
						if (item.offset < minDistanceToMid) {
							finalReuslt = item.result;
							minDistanceToMid = item.offset;
						}
					})
				}

				//直接返回结果
				return finalReuslt
			},

			/*辅助函数，判断每一行座位从i列到j列是否全部空余且连续
			 *
			 */
			checkRowSeatContinusAndEmpty: function(rowNum, startPos, endPos) {
				let isValid = true;
				for (let i = startPos; i <= endPos; i++) {
					if (this.seatArray[rowNum][i].type !== 0) {
						isValid = false;
						break;
					}
				}
				return isValid
			},
			//辅助函数：返回每一行的某个合理位置的座位数组
			generateRowResult: function(row, startPos, endPos) {
				let result = [];
				for (let i = startPos; i <= endPos; i++) {
					result.push([row, i])
				}
				return result
			},
			//辅助函数:智能推荐的选座操作
			chooseSeat: function(result) {
				let opt = this.optArr
				let oldArray = this.seatArray.slice();
				for (let i = 0; i < result.length; i++) {
					//选定座位
					oldArray[result[i][0]][result[i][1]].rowIndex = result[i][0]
					oldArray[result[i][0]][result[i][1]].colIndex = result[i][1]
					oldArray[result[i][0]][result[i][1]].type = 1
					this.optArr.push(oldArray[result[i][0]][result[i][1]])
				}
				this.seatArray = oldArray;
			},
		}
	}
</script>

<style lang="scss">
	.sel-seat {
		display: flex;
		flex-direction: column;
		width: 100%;
		height: 100vh;

		.seat-head {
			background-color: #ffffff;
			display: flex;
			flex-direction: column;
			padding: 20rpx 30rpx;
			position: relative;
			z-index: 5;

			.sh-title {
				font-size: 32rpx;
				font-weight: bold;
				color: #333333;
			}

			.sh-info {
				font-size: 24rpx;
				color: #999999;
				margin-top: 10rpx;
			}
		}

		.seat-main {
			width: 100%;
			position: relative;
			padding: 10rpx;

			.vm-area {
				width: 750rpx;
			}

			.sm-title {
				background-color: #dddddd;
				width: 380rpx;
				height: 34rpx;
				transform: perspective(34rpx) rotateX(-10deg);
				margin: 0 auto;
				display: flex;
				align-items: center;
				justify-content: center;
				position: relative;
				z-index: 2;

				.text {
					font-size: 24rpx;
					color: #333333;
				}
			}

			.sm-screen {
				// width: 100rpx
				
				        
				width:fit-content;
				padding: 10rpx;
				height: 30rpx;
				border: 1rpx solid #cccccc;
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;
				margin: 48rpx auto 0;
				border-radius: 4rpx;
				//position: relative;
				// z-index: 1;

				.text {
					font-size: 20rpx;
					color: #999999;
				}
			}

			.sm-line-center {
				height: 610rpx;
				width: 0;
				border: 1rpx dashed #e5e5e5;
				position: fixed;
				left: 50%;
				top: 0;
				display: block;
				z-index: 0;
				transform: translateX(-50%);
			}

			.fix-tips {
				display: flex;
				align-items: center;
				justify-content: center;
				font-size: 24rpx;
				position: fixed;
				bottom: 214rpx;
				left: 0;
				width: 100%;
				z-index: 1;
				padding: 20rpx;

				.v-tips {
					display: flex;
					align-items: center;
					color: #999;
					margin: 0 10rpx;

					.text {
						margin-left: 10rpx;
					}
				}
			}

			// seat style
			.sm-cell {
				display: flex;
				margin-top: 20rpx;
				align-items: center;
				justify-content: center;
				position: relative;
				z-index: 2;

				.sm-icon {
					width: 100%;
					height: 100%;
				}
			}

			.sm-line-index {
				position: fixed;
				top: 114rpx;
				left: 20rpx;
				border-radius: 14rpx;
				overflow: hidden;
				background-color: rgba($color: #000000, $alpha: 0.3);
				z-index: 3;
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;
				padding-bottom: 20rpx;
				width: 30rpx;

				.text {
					font-size: 24rpx;
					color: #ffffff;
					width: 100%;
					text-align: center;
					margin-top: 20rpx;
				}
			}
		}

		.seat-foot {
			margin-top: auto;
			background-color: #ffffff;
			padding: 20rpx 30rpx;
			position: relative;
			z-index: 5;

			.sf-recommend {
				display: flex;
				align-items: center;
				justify-content: center;
				padding-bottom: 20rpx;

				.text {
					font-size: 28rpx;
					color: #666666;
				}

				.sfr-tag {
					width: 110rpx;
					height: 60rpx;
					border-radius: 4rpx;
					border: 1rpx solid #ccc;
					display: flex;
					align-items: center;
					justify-content: center;
					margin-left: 20rpx;
				}
			}

			.sf-arselect {
				@extend .sf-recommend;

				.text {
					font-size: 24rpx;
					color: #666666;
				}

				.price {
					font-size: 20rpx;
					color: red;
				}

				.scr-wrap {
					display: flex;
					white-space: nowrap;
				}

				.sfr-selt {
					min-width: 130rpx;
					height: 60rpx;
					border-radius: 4rpx;
					border: 1rpx solid #ccc;
					display: flex;
					align-items: flex-start;
					justify-content: center;
					flex-direction: column;
					margin-left: 20rpx;
					position: relative;
					margin-left: 20rpx;
					padding-left: 10rpx;

					.sfr-close {
						position: absolute;
						right: 6rpx;
						top: 10rpx;
						font-size: 20rpx;
						color: #999;
					}
				}
			}

			.f-btn {
				background-color: #F45664;
				width: 100%;
				height: 90rpx;
				line-height: 90rpx;
				text-align: center;
				border-radius: 10rpx;

				.text {
					color: #ffffff;
					font-size: 36rpx;
				}

				&.disabled {
					background-color: #cbcbcb;
					opacity: .8;
				}
			}
		}
	}
</style>
